#include "OverLoad.h"
#include "../function_interface.h"
#include "../types.h"
#include <stdio.h>
#include "OverUnderX.h"
#include "../logInterface.h"
#if 1

typedef struct {
    int   olMultiple_100;//过载倍率,实际功率大于该值表示进入下一级过载,比如大于1倍则认为是1.1倍过载(放大100倍,1.1倍就是110),
    int   olThrEnterPower_1kx;//过载进入判定阈值(倍率的基础上需要加上该值)
    int   olThrEnterTime_1s;//过载进入判定时间
    int   olThrExitPower_1kx;//过载退出判定阈值(倍率的基础上需要减去该值)
    int   olThrExitTime_1s;//过载退出判定时间
}overLoadConfType;


typedef struct {
    int      olEnterTime_1s;//当前已进入判定阈值的时间,该值超过olThrEnterTime_1s判定为该级过载
    int      olExitTime_1s;//当前已退出判定阈值的时间,该值超过olThrExitTime_1s判定为脱离该级过载
    uint32_t olKeepTime_1s;//该级过载已持续的时间(保持该级过载不变的情况下).
    uint32_t olTotalTime_1s;//该级过载总工作的时间.
    uint32_t olOnTime_1s;//系统功率级别为该级过载已持续的时间().
}overLoadRealtimeInfoType;

#define INDEX_LEVEL_START 10
#define INDEX_LEVEL_END 14

const static overLoadConfType overLoadConfig[]=
//需要几段,设置几段,但顺序必须由小到大
{
    {//0.0倍
        .olMultiple_100        = 0,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.1倍
        .olMultiple_100        = 10,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.2倍
        .olMultiple_100        = 20,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.3倍
        .olMultiple_100        = 30,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.4倍
        .olMultiple_100        = 40,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.5倍
        .olMultiple_100        = 50,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.7倍
        .olMultiple_100        = 60,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.6倍
        .olMultiple_100        = 70,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.8倍
        .olMultiple_100        = 80,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//0.9倍
        .olMultiple_100        = 90,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//1.0倍过载
        .olMultiple_100        = 100,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 5,
    },
    {//1.1倍过载
        .olMultiple_100        = 110,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 2,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 2,
    },
    {
        .olMultiple_100        = 120,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 130,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 140,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 150,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 160,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 170,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 180,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 190,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    },
    {
        .olMultiple_100        = 200,
        .olThrEnterPower_1kx = 0,
        .olThrEnterTime_1s   = 1,
        .olThrExitPower_1kx  = 0,
        .olThrExitTime_1s    = 1,
    }
};


static overLoadRealtimeInfoType overLoadRealtimeInfo[sizeof(overLoadConfig)/sizeof(overLoadConfig[0])];

static int overLoadLevel;//当前过载级数(0级表示未过载,N级表示overLoadConfig[N].olProportion倍过载)

void OverLoad_1SecondPerLoop(const void* pPara)
//过载检测,需要1s调用一次.
{
    int realTimeOLLevel=0;//实时过载级别

    int index=0;
    float actPower,ratedPower;
    int currPower_1kx=0,thrPower_1kx,enterThrPower_1kx,exitThrPower_1kx;
    int enterThrTime_1s/*进入该级的判定时间阈值*/,exitThrTime_1s/*退出该级的判定时间阈值*/;
    fpagDataFsm_t fsm;

    const overLoadConfType* pOverLoadConfig = overLoadConfig;

    overLoadRealtimeInfoType* pOverLoadRealtimeInfo = overLoadRealtimeInfo;

    if(FUNCINF_ERR_NONE == FuncInf_GetFsm(FUNCINF_FSM_TYPE_THIS_TIME,&fsm))
    {
        if((fsm == FUNCINF_FSM_IDLE) || (fsm == FUNCINF_FSM_FAULT) || (fsm == FUNCINF_FSM_STOP))
        {
            return;
        }
    }
    else
    {
        return;
    }

    FuncInf_GetPower(FUNCINF_PWR_TYPE_ACT,&actPower);
    currPower_1kx = (int)actPower;
    for(index = INDEX_LEVEL_START; index < INDEX_LEVEL_END; index++)
    {
        //功率阈值
        if(FuncInf_GetExtremeValue(FUNCINF_EXTR_VAL_TYPE_AC_P_MAX,&ratedPower) == FUNCINF_ERR_NONE)
        {
            thrPower_1kx = pOverLoadConfig[index].olMultiple_100 * (int)(ratedPower/1.3/100);
        }
        else
        {
            thrPower_1kx = pOverLoadConfig[index].olMultiple_100 * RATED_POWER/100;
        }
        enterThrPower_1kx = thrPower_1kx + pOverLoadConfig[index].olThrEnterPower_1kx;
        exitThrPower_1kx = thrPower_1kx - pOverLoadConfig[index].olThrExitPower_1kx;

        //时间阈值
        enterThrTime_1s = pOverLoadConfig[index].olThrEnterTime_1s;
        exitThrTime_1s = pOverLoadConfig[index].olThrExitTime_1s;
        
        if(currPower_1kx > enterThrPower_1kx)
        //满足该级进入判定
        {
            if(pOverLoadRealtimeInfo[index].olEnterTime_1s++ >= enterThrTime_1s)
            {
                pOverLoadRealtimeInfo[index].olKeepTime_1s++;//本次该级过载持续的时间
                pOverLoadRealtimeInfo[index].olTotalTime_1s++;//自arm启动以来该级过载总共的时间
            }
        }
        else
        {
            pOverLoadRealtimeInfo[index].olEnterTime_1s = 0;
        }
        
        if(currPower_1kx <= exitThrPower_1kx)
        //满足该级退出判定
        {
            if(pOverLoadRealtimeInfo[index].olExitTime_1s++ >= exitThrTime_1s)
            {
                pOverLoadRealtimeInfo[index].olKeepTime_1s = 0;
            }
        }
        else
        {
            pOverLoadRealtimeInfo[index].olExitTime_1s = 0;
        }

        if(pOverLoadRealtimeInfo[index].olKeepTime_1s)
        {
            realTimeOLLevel = index;

        }

#if 1 //一般我们对外是宣传的这种情况
        if(pOverLoadConfig[index].olMultiple_100 == 110)
        //1.1倍12分钟过载
        {
            if(pOverLoadRealtimeInfo[index].olKeepTime_1s >= 60*12)
            {
                // logInterfaceLogAdd(LOG_CLASS_SPECIAL, LOG_MAINTYPE_FAULT, 250, COM_DATA_TYPE_NONE, NULL);
                //关机
                FuncInf_TurnOnOff(FUNCINF_OPERATOR_OVER_LOAD,NULL,FUNCINF_TURN_OFF);
                pOverLoadRealtimeInfo[index].olKeepTime_1s = 0;
                continue;
            }
        }
        if(pOverLoadConfig[index].olMultiple_100 == 120)
        //1.2倍2分钟过载
        {
            if(pOverLoadRealtimeInfo[index].olKeepTime_1s >= 60*2)
            {
                // logInterfaceLogAdd(LOG_CLASS_SPECIAL, LOG_MAINTYPE_FAULT, 250, COM_DATA_TYPE_NONE, NULL);
                //关机
                FuncInf_TurnOnOff(FUNCINF_OPERATOR_OVER_LOAD,NULL,FUNCINF_TURN_OFF);
                pOverLoadRealtimeInfo[index].olKeepTime_1s = 0;
                continue;
            }
        }

        if(pOverLoadConfig[index].olMultiple_100 >= 130)
        //1.2倍以上过载1.5分钟就关机
        {
            if(pOverLoadRealtimeInfo[index].olKeepTime_1s >= 90)
            {
                // logInterfaceLogAdd(LOG_CLASS_SPECIAL, LOG_MAINTYPE_FAULT, 250, COM_DATA_TYPE_NONE, NULL);
                //关机
                FuncInf_TurnOnOff(FUNCINF_OPERATOR_OVER_LOAD,NULL,FUNCINF_TURN_OFF);
                pOverLoadRealtimeInfo[index].olKeepTime_1s = 0;
                continue;
            }
        }

#endif


#if 0 //特殊情况
        //1.1倍长期过载
        if(pOverLoadConfig[index].olMultiple_100 == 100)
        {
            // PowerLimit_SetPowerLimit(POWER_LIMIT_EVENT_PCS_OVER_LOAD_DERATE,
            //     POWER_LIMIT_EVENT_RISE,RATED_POWER,RATED_POWER);
            // Logs_Add("overload","multiple1.1_power_run_over_10min","0");

        }

        if(pOverLoadRealtimeInfo[index].olKeepTime_1s >= 10*60)
        //1.2倍10分钟过载
        {
            if(pOverLoadConfig[index].olMultiple_100 == 110)
            {
                // PowerLimit_SetPowerLimit(POWER_LIMIT_EVENT_PCS_OVER_LOAD_DERATE,
                //     POWER_LIMIT_EVENT_RISE,RATED_POWER,RATED_POWER);
                // Logs_Add("overload","multiple1.2_power_run_over_10sec","0");

                //关机
                FuncInf_TurnOnOff(FUNCINF_OPERATOR_OVER_LOAD,NULL,FUNCINF_TURN_OFF);
            }
        }
#endif

    }
    
    if(overLoadLevel != realTimeOLLevel)
    //得到当前的功率级别
    {
        overLoadLevel = realTimeOLLevel;
        pOverLoadRealtimeInfo[overLoadLevel].olOnTime_1s=0;
        printf("Current Power Level is:%d.\n",overLoadLevel);
    }
    else
    {
        pOverLoadRealtimeInfo[overLoadLevel].olOnTime_1s++;
    }

#if 0
    if((overLoadLevel <= 10)&&
        (pOverLoadRealtimeInfo[overLoadLevel].olOnTime_1s == 10))
    //功率在额定范围内保持10秒以上,则放开功率限制
    {
        printf("功率级别:%d.功率在额定范围内保持10秒以上,放开功率限制.\n",overLoadLevel);
        // PowerLimit_SetPowerLimit(POWER_LIMIT_EVENT_PCS_OVER_LOAD_DERATE,
        //     POWER_LIMIT_EVENT_DOWN,0,0);
        // Logs_Add("overload_finish","below_multiple1.0_power_run_over_10sec","0");
    }
#endif

}


#endif

